package com.tgpay.iot.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.TreeMap;

/**
 * 签名验证服务
 */
@Service
@Slf4j
public class SignatureService {
    
    @Value("${app.api.secret-key:your-secret-key-here}")
    private String secretKey;
    
    /**
     * 验证签名
     * @param params 请求参数
     * @param signature 客户端签名
     * @param timestamp 时间戳
     * @return 验证结果
     */
    public boolean verifySignature(Map<String, Object> params, String signature, Long timestamp) {
        try {
            // 检查时间戳（5分钟内有效）
            long currentTime = System.currentTimeMillis();
            if (Math.abs(currentTime - timestamp) > 5 * 60 * 1000) {
                log.warn("请求时间戳过期，当前时间：{}，请求时间：{}", currentTime, timestamp);
                return false;
            }
            
            // 生成服务端签名
            String serverSignature = generateSignature(params, timestamp);
            
            // 比较签名
            boolean isValid = serverSignature.equals(signature);
            if (!isValid) {
                log.warn("签名验证失败，服务端签名：{}，客户端签名：{}", serverSignature, signature);
            }
            
            return isValid;
        } catch (Exception e) {
            log.error("签名验证异常", e);
            return false;
        }
    }
    
    /**
     * 生成签名
     * @param params 参数
     * @param timestamp 时间戳
     * @return 签名
     */
    public String generateSignature(Map<String, Object> params, Long timestamp) {
        // 创建有序的参数映射
        TreeMap<String, Object> sortedParams = new TreeMap<>(params);
        
        // 添加时间戳
        sortedParams.put("timestamp", timestamp);
        
        // 构建签名字符串
        StringBuilder signStr = new StringBuilder();
        for (Map.Entry<String, Object> entry : sortedParams.entrySet()) {
            if (entry.getValue() != null && !"signature".equals(entry.getKey())) {
                signStr.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        
        // 添加密钥
        signStr.append("key=").append(secretKey);
        
        // 生成MD5签名
        String signature = DigestUtils.md5Hex(signStr.toString()).toUpperCase();
        
        log.debug("签名字符串：{}，生成签名：{}", signStr.toString(), signature);
        
        return signature;
    }
    
    /**
     * 为响应生成签名
     * @param data 响应数据
     * @return 签名
     */
    public String generateResponseSignature(Object data) {
        long timestamp = System.currentTimeMillis();
        String dataStr = data != null ? data.toString() : "";
        String signStr = "data=" + dataStr + "&timestamp=" + timestamp + "&key=" + secretKey;
        return DigestUtils.md5Hex(signStr).toUpperCase();
    }
}